package com.nineclock.document.service.impl;
import java.util.Date;
import java.util.*;


import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nineclock.common.entity.PageResult;
import com.nineclock.common.entity.Result;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.threadlocal.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.document.dto.DocFileDto;
import com.nineclock.document.dto.DocFolderDto;
import com.nineclock.document.dto.DocumentDto;
import com.nineclock.document.dto.DocumentUserDTO;
import com.nineclock.document.enums.DocumentPermissionEnum;
import com.nineclock.document.mapper.DocCollaborationsMapper;
import com.nineclock.document.mapper.DocFileMapper;
import com.nineclock.document.mapper.DocFolderMapper;
import com.nineclock.document.pojo.DocCollaborations;
import com.nineclock.document.pojo.DocFile;
import com.nineclock.document.pojo.DocFolder;
import com.nineclock.document.service.DocFileService;
import com.nineclock.system.dto.SysCompanyUserDTO;
import com.nineclock.system.feign.SysCompanyUserFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.print.Doc;
import java.util.stream.Collectors;

@Service
@Transactional
public class DocFileServiceImpl implements DocFileService {
    @Autowired
    private DocFolderMapper docFolderMapper;
    @Autowired
    private DocFileMapper docFileMapper;
    @Autowired
    private SysCompanyUserFeign sysCompanyUserFeign;
    @Override
    public DocumentDto listFolderAndFile(Long parentFoldId) {
        Long companyId = CurrentUserHolder.get().getCompanyId();
        //查文件夹
        List<DocFolder> docFolderList = listFolder(companyId, parentFoldId);
        List<DocFolderDto> docFolderDtoList = BeanHelper.copyWithCollection(docFolderList, DocFolderDto.class);
        //查文件
        List<DocFileDto> docFileList = listFile(parentFoldId,companyId);
        DocumentDto documentDto = new DocumentDto();
        documentDto.setFolders(docFolderDtoList);
        documentDto.setFiles(docFileList);

        return documentDto;
    }

    @Override
    public DocFileDto getFileByFileId(Long id) {
        LambdaQueryWrapper<DocFile> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DocFile::getId,id);
        DocFile docFile = docFileMapper.selectOne(wrapper);
        return BeanHelper.copyProperties(docFile,DocFileDto.class);
    }

    @Override
    public void insertFile(Map<String,Object> map) {
        if (map == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        String content = (String) map.get("content");
        String filePath = (String) map.get("filePath");
        Integer folderId = (Integer) map.get("folderId");
        String name = (String) map.get("name");
        int length = content.getBytes().length;
        DocFile docFile = new DocFile();
        docFile.setFolderId(Long.valueOf(folderId));
        docFile.setName(name);
        docFile.setFilePath(filePath);
        docFile.setFileSize(length+"B");
        docFile.setStatus((short)1);
        docFile.setContent(content);
        docFile.setPermission((short)1);
        docFile.setType(null);
        docFile.setCompanyId(CurrentUserHolder.get().getCompanyId());
        docFile.setCreateUserId(CurrentUserHolder.get().getCompanyUserId());
        docFile.setCreateTime(new Date());
        docFile.setUpdateUserId(CurrentUserHolder.get().getCompanyUserId());
        docFile.setUpdateTime(new Date());

        docFileMapper.insert(docFile);
    }

    @Override
    public void updateFile(Map<String, Object> map) {
        String content = (String) map.get("content");
        String filePath = (String) map.get("filePath");
        Integer folderId = (Integer) map.get("folderId");
        Integer id = (Integer) map.get("id");
        String name = (String) map.get("name");
        DocFile docFile = new DocFile();
        docFile.setFolderId(Long.valueOf(folderId));
        docFile.setName(name);
        docFile.setFilePath(filePath);
        docFile.setFileSize(content.getBytes().length+"B");
        docFile.setStatus((short)1);
        docFile.setContent(content);
        docFile.setUpdateUserId(CurrentUserHolder.get().getCompanyUserId());
        docFile.setUpdateTime(new Date());

        LambdaQueryWrapper<DocFile> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DocFile::getFolderId,folderId);
        wrapper.eq(DocFile::getName,name);
        docFileMapper.update(docFile,wrapper);
    }


    private List<DocFileDto> listFile(Long parentFoldId, Long companyId) {
        Long id = CurrentUserHolder.get().getCompanyUserId();
        List<DocFile> docFileList = new ArrayList<>();
        //公共读写
        LambdaQueryWrapper<DocFile> wrapperPublic = new LambdaQueryWrapper<>();
        wrapperPublic.eq(DocFile::getCompanyId,companyId);
        wrapperPublic.eq(DocFile::getFolderId,parentFoldId);
        wrapperPublic.eq(DocFile::getStatus,1);
        wrapperPublic.in(DocFile::getPermission, DocumentPermissionEnum.ALL_READ.getPermission(),DocumentPermissionEnum.ALL_READ_WRITE.getPermission());
        List<DocFile> docFilesPublic = docFileMapper.selectList(wrapperPublic);

        if (!CollectionUtils.isEmpty(docFilesPublic)) {
            docFileList.addAll(docFilesPublic);
        }
        //私有
        LambdaQueryWrapper<DocFile> wrapperPersonal = new LambdaQueryWrapper<>();
        wrapperPersonal.eq(DocFile::getCompanyId,companyId);
        wrapperPersonal.eq(DocFile::getFolderId,parentFoldId);
        wrapperPersonal.eq(DocFile::getStatus,1);
        wrapperPersonal.eq(DocFile::getCreateUserId,id);
        wrapperPersonal.in(DocFile::getPermission, DocumentPermissionEnum.PRIVATE_READ_WRITE.getPermission());
        List<DocFile> docFilePersonal = docFileMapper.selectList(wrapperPersonal);
        if (!CollectionUtils.isEmpty(docFilePersonal)) {
            docFileList.addAll(docFilePersonal);
        }
        //协作者
        List<DocFile> docFileHelper = docFileMapper.selectListByCollaboration(companyId,CurrentUserHolder.get().getCompanyUserId(),parentFoldId);
        if (!CollectionUtils.isEmpty(docFileHelper)) {
            docFileList.addAll(docFileHelper);
        }
        //*****************************************
        HashSet<DocFile> docFileHashSet = new HashSet<>(docFileList);
        Set<DocFileDto> docFileDtos = BeanHelper.copyWithCollection(docFileHashSet, DocFileDto.class);
        List<DocFileDto> dtoList = docFileDtos.stream().map(docFileDto -> {
            SysCompanyUserDTO companyUserDTO1 = sysCompanyUserFeign.queryCompanyUserById(docFileDto.getCreateUserId()).getData();
            if (companyUserDTO1 != null){
                docFileDto.setUserName(companyUserDTO1.getUserName());
            }
            SysCompanyUserDTO companyUserDTO2 = sysCompanyUserFeign.queryCompanyUserById(docFileDto.getUpdateUserId()).getData();
            if (companyUserDTO2 != null) {
                docFileDto.setUpdateUserName(companyUserDTO2.getUserName());
            }
            return docFileDto;
        }).collect(Collectors.toList());
        return dtoList;
    }

    private List<DocFolder> listFolder(Long companyId,Long parentFoldId) {
        LambdaQueryWrapper<DocFolder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DocFolder::getCompanyId,companyId);
        wrapper.eq(DocFolder::getParentId,parentFoldId);
        wrapper.eq(DocFolder::getStatus,1);
        List<DocFolder> docFolders = docFolderMapper.selectList(wrapper);
        return docFolders;

    }
}
